﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Windows;
using System.Data;
using System.Windows.Input;
using produccion.modelo;
using produccion.AccesoDatos;
using System.ComponentModel;
using System.Diagnostics;
using System.Collections.Specialized;
using System.Windows.Controls;


namespace produccion.vistamodelo
{
    class VMpermiso : ViewModelBase, IDataErrorInfo
    {

        ProcesoProduccionRepositorio _rep=new ProcesoProduccionRepositorio();
        
        public VMpermiso() {
            try {

                usuarios = new clases.CLSMAEUSUP().listarUsuario();

                if (MDOgeneral.conexion == null || MDOgeneral.conexion.State == ConnectionState.Closed)
                {
                    MDOgeneral.conectar();
                }
                strTituloVentana = "Permisos - Usuario: " + MDOgeneral.usuario + " - [FRMpermiso]";
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
           }
        }
        
        public void consultar(string codusu) {
            try {

                hijos.Clear();
                padre = new arbol { id = 0, nombre = "" };
                val = new clases.CLSMAEOPCP { CODUSU=codusu}.consultar();
                consultarMenu(0, null);
                logCambio = false;
            
            }
            catch (Exception ex) {MessageBox.Show(ex.Message); }
        
        }

        private string _strTituloVentana;
        public string strTituloVentana
        {
            get { return _strTituloVentana; }
            set { _strTituloVentana = value; base.OnPropertyChanged("strTituloVentana"); }
        }

        public class arbol : ObservableObject
        {

            private ObservableCollection<arbol> _hijos = new ObservableCollection<arbol>();
            public ObservableCollection<arbol> hijos
            {
                get { return _hijos; }
                set
                {
                    _hijos = value;

                    RaisePropertyChangedEvent("hijos");
                }
            }

            private arbol _padre;
            public arbol padre
            {
                get { return _padre; }
                set
                {
                    _padre = value;
                    RaisePropertyChangedEvent("padre");
                }
            }

            private int _id;
            public int id
            {
                get { return _id; }
                set
                {
                    _id = value;
                    RaisePropertyChangedEvent("id");
                }
            }

            private string _nombre;
            public string nombre
            {
                get { return _nombre; }
                set
                {
                    _nombre = value;
                    RaisePropertyChangedEvent("nombre");
                }
            }

            private string _padreid;
            public string padreid
            {
                get { return _padreid; }
                set
                {
                    _padreid = value;
                    RaisePropertyChangedEvent("padreid");
                }
            }

            private string _orden;
            public string orden
            {
                get { return _orden; }
                set
                {
                    _orden = value;
                    RaisePropertyChangedEvent("orden");
                }
            }

            private string _usuario;
            public string usuario
            {
                get { return _usuario; }
                set
                {
                    _usuario = value;
                    permiso = String.IsNullOrEmpty(_usuario) ? "N" : "S";
                    RaisePropertyChangedEvent("usuario");
                }
            }

            private string _formulario;
            public string formulario
            {
                get { return _formulario; }
                set
                {
                    _formulario = value;
                    RaisePropertyChangedEvent("formulario");
                }
            }

            private string _tipo;
            public string tipo
            {
                get { return _tipo; }
                set
                {

                    _tipo = value;
                    RaisePropertyChangedEvent("tipo");
                }
            }

            private string _permiso = "N";
            public string permiso
            {
                get { return _permiso; }
                set
                {
                    _permiso = value;

                
                
                    if (tipo.Equals("M") && permiso.Equals("N")) NoPermitirHijos(hijos);

                    if (tipo.Equals("M") && _permiso.Equals("S")) PermitirHijos(hijos);

                    if (_permiso.Equals("S")) { PermitirPadres(padre); }

                    RaisePropertyChangedEvent("permiso");
                }
            }

            public Boolean PermitirPadres(arbol _padre)
            {
                try
                {
                    if (_padre != null)
                    {
                        _padre._permiso = "S";
                        _padre.RaisePropertyChangedEvent("permiso");
                        _padre._IsExpanded = true;
                        _padre.RaisePropertyChangedEvent("IsExpanded");
                        if (_padre != null)
                        {
                            PermitirPadres(_padre.padre);
                        }
                    }
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
                return true;
            }

            public Boolean PermitirHijos(ObservableCollection<arbol> _lisHijos)
            {
                try
                {
                    if (_lisHijos != null)
                    {
                        for (int i = 0; i <= _lisHijos.Count - 1; i++)
                        {
                            _lisHijos[i]._permiso = "S";
                            _lisHijos[i].RaisePropertyChangedEvent("permiso");
                            _lisHijos[i]._IsExpanded = true;
                            _lisHijos[i].RaisePropertyChangedEvent("IsExpanded");
                            PermitirHijos(_lisHijos[i].hijos);
                        }
                    }
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
                return true;
            }

            public Boolean NoPermitirHijos(ObservableCollection<arbol> _lisHijos)
            {
                try
                {
                    if (_lisHijos != null)
                    {
                        for (int i = 0; i <= _lisHijos.Count - 1; i++)
                        {

                            _lisHijos[i]._permiso= "N";
                            _lisHijos[i].RaisePropertyChangedEvent("permiso");
                            _lisHijos[i]._IsExpanded = true;
                            _lisHijos[i].RaisePropertyChangedEvent("IsExpanded");
                             NoPermitirHijos(_lisHijos[i].hijos);
                        }
                    }
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
                return true;
            }
            
            public Boolean preguntar = false;
              
            private Boolean _IsExpanded;
            public Boolean IsExpanded
            {
                get { return _IsExpanded; }
                set
                {
                    _IsExpanded = value;
                    RaisePropertyChangedEvent("IsExpanded");
                }
            }

            private Boolean _IsSelected;
            public Boolean IsSelected
            {
                get { return _IsSelected; }
                set
                {
                    _IsSelected = value;
                    RaisePropertyChangedEvent("IsSelected");
                }
            }

        }
        
        private arbol _padre = new arbol { id = 0, nombre = "" };
        public arbol padre
        {
            get { return _padre; }
            set
            {
                _padre = value;
                base.OnPropertyChanged("padre");
            }
        }

        private arbol _sel = new arbol();
        public arbol sel
        {
            get { return _sel; }
            set
            {
                _sel = value;
                base.OnPropertyChanged("sel");
            }
        }

        private ObservableCollection<arbol> _hijos = new ObservableCollection<arbol>();
        public ObservableCollection<arbol> hijos
        {
            get { return _hijos; }
            set
            {
                _hijos = value;
                base.OnPropertyChanged("hijos");
            }
        }

        public DataTable val { get; set; }
        public void consultarMenu(int indicepadre, arbol nodopadre)
        {

            DataView vista = new DataView(val);
            vista.RowFilter = val.Columns["CODPADRE_OPC"].ColumnName + " = " + indicepadre;
            foreach (DataRowView r in vista)
            {
                arbol nodo = new arbol
                {
                    
                    padreid = r["CODPADRE_OPC"].ToString(),
                    tipo = r["TIPO_OPC"].ToString(),
                    id = Convert.ToInt32(r["CODHIJO_OPC"]),
                    orden = r["ORDEN_OPC"].ToString(),
                    formulario = r["FORMUL_OPC"].ToString(),
                    usuario = r["CODUSU_OPU"].ToString(),
                    nombre = r["NOMBRE_OPC"].ToString().Trim(),
                    preguntar=true,
                   
         

                };

                nodo.PropertyChanged +=OnPermisoPropertyChanged;

                if (nodopadre == null)
                {
                    nodo.padre = padre;
                    hijos.Add(nodo);
                    padre.hijos = hijos;
                }
                else
                {
                    nodo.padre = nodopadre;
                    nodopadre.hijos.Add(nodo);

                }

                consultarMenu(Convert.ToInt32(r["CODHIJO_OPC"]), nodo);

            }

          
        }


        private List<clases.CLSMAEUSUP> _usuarios = new List<clases.CLSMAEUSUP>();
        public List<clases.CLSMAEUSUP> usuarios
        {
            get { return _usuarios; }
            set { _usuarios = value;
            base.OnPropertyChanged("usuarios");
            }
        }


        private clases.CLSMAEUSUP _selUsuario;
        public clases.CLSMAEUSUP selUsuario {
            get { return _selUsuario; }
            set { _selUsuario = value;

            hijos.Clear();  
            if (_selUsuario != null) {
                consultar(String.IsNullOrEmpty(_selUsuario.CODUSU_USU) ? "" :_selUsuario.CODUSU_USU);
            }
            base.OnPropertyChanged("selUsuario");
            }
        }

        private string _texMenBus;
        public string texMenBus {
            get { return _texMenBus; }
            set { _texMenBus = value;
            base.OnPropertyChanged("texMenBus");
            _buscandoapp = null;
            }
        }
                
        private Boolean _camm = false;
        public Boolean camm
        {
            get { return _camm; }
            set
            {
                _camm = value;
              base.OnPropertyChanged("camm");
            }
        }

        //Busqueda en menu
        IEnumerator<arbol> _buscandoapp;
        public void PerformSearch()
        {
            if (String.IsNullOrEmpty(texMenBus) || String.IsNullOrWhiteSpace(texMenBus))
                return;

            if (_buscandoapp == null || !_buscandoapp.MoveNext())
                this.VerifyMatchingItemEnumerator();

            var item = _buscandoapp.Current;

            if (item == null)
                return;
            camm = true;
            item.IsExpanded = true;
            item.IsSelected = true;
            sel = item;

            arbol a = item;
            msn.texto = "Coincidencia encontrada '" + item.nombre + "'.";
            msn.tipo = true;
          
            while (a.padre != null)
            {
                a.padre.IsExpanded = true;
                a.padre.IsSelected = false;
                a = a.padre;
            }
        }

        void VerifyMatchingItemEnumerator()
        {
            var matches = this.FindMatches(texMenBus, padre);
            _buscandoapp = matches.GetEnumerator();

            if (!_buscandoapp.MoveNext())
            {
                msn.texto = "No se encuentran coincidencias para su busqueda.";
                msn.tipo = false;
            }
        }
        IEnumerable<arbol> FindMatches(string searchText, arbol item)
        {
            if (item.nombre.ToUpper().Contains(searchText.ToUpper()))
                yield return item;

            foreach (arbol child in item.hijos)
                foreach (arbol match in this.FindMatches(searchText, child))
                    yield return match;
        }
                
        RelayCommand _cmdBuscar;
        public ICommand cmdBuscar
        {
            get
            {

                if (_cmdBuscar == null)
                {
                    _cmdBuscar = new RelayCommand(Buscar);
                }
                return _cmdBuscar;
            }
        }

        RelayCommand _cmdGuardar;
        public ICommand cmdGuardar
        {
            get
            {

                if (_cmdGuardar == null)
                {
                    _cmdGuardar = new RelayCommand(r => Guardar());
                }
                return _cmdGuardar;
            }
        }

        RelayCommand _cmdSalir;
        public ICommand cmdSalir
        {
            get
            {

                if (_cmdSalir == null)
                {
                    _cmdSalir = new RelayCommand(Salir);
                }
                return _cmdSalir;
            }
        }
               
        public void Buscar(object txtBuscar) {
            try {
         
                PerformSearch();  
                ((TextBox)txtBuscar).Focus();
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
        }

        public List<Mpermiso> lisPermisos = new List<Mpermiso>();
        
        public void Guardar() {
            try {
                lisPermisos.Clear();
                cargarListaPermisos(null);

                if (_rep.GuardarPermisoUsuarios(selUsuario.CODUSU_USU, lisPermisos))
                {

                    msn.texto = "Los permisos fueron guardados con exito.";
                    msn.tipo = true;
                }
                else {

                    msn.texto = "Los permisos no pueden ser guardados.";
                    msn.tipo=false;                
                
                }
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
        }

        public void Salir(object paremetro) {
            try {
                Window w = (Window)paremetro;
                w.Close();
            
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
        }
        
        public void cargarListaPermisos(arbol nodo)
        {
            try
            {
                if (nodo != null) {
                    if (nodo.permiso.Equals("S"))
                    {
                        lisPermisos.Add(new Mpermiso { strCodHijo = nodo.id.ToString(), strPermiso = nodo.permiso, strNombre = nodo.nombre });
                    }
                }else{
                nodo=new arbol();
                nodo.hijos=hijos;
                }
                foreach (arbol r in nodo.hijos) {
                    cargarListaPermisos(r);
                }
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
        }
        
        private MDOgeneral.mensaje _msn = new MDOgeneral.mensaje();
        public MDOgeneral.mensaje msn {
            get { return _msn; }
            set { _msn = value;
            base.OnPropertyChanged("msn");
            }
        }

        private Boolean _logCambio = false;
        public Boolean logCambio {
            get { return _logCambio; }
            set { _logCambio = value;
            base.OnPropertyChanged("logCambio");
            }
        }

        void OnPermisoPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "permiso") {
                logCambio = true;
            }
        }

        #region IDataErrorInfo Members

        string IDataErrorInfo.Error { get { return null; } }

        string IDataErrorInfo.this[string propertyName]
        {
            get { return this.GetValidationError(propertyName); }
        }

        #endregion

        #region Validation

        /// <summary>
        /// Returns true if this object has no validation errors.
        /// </summary>
        public bool IsValid
        {
            get
            {
                foreach (string property in ValidatedProperties)
                    if (GetValidationError(property) != null)
                        return false;

                return true;
            }
        }

        static readonly string[] ValidatedProperties = 
        { 
            "selUsuario"
                
        };

        string GetValidationError(string propertyName)
        {
            if (Array.IndexOf(ValidatedProperties, propertyName) < 0)
                return null;

            string error = null;

            switch (propertyName)
            {
                case "selUsuario":
                    error = this.ValidateselUsuario();
                    break;
               default:
                    Debug.Fail("Unexpected property being validated on Customer: " + propertyName);
                    break;
            }

            return error;
        }

        string ValidateselUsuario()
        {
            if (selUsuario == null) {
                return "Debe seleccionar un usuario.";
            
            }
            return null;
        }







        #endregion

    }
}
